home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
101-125
/
scopedisk120
/
seehear
/
seehear.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
42KB
|
1,435 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <fcntl.h>
#include <stdio.h>
#include <intuition/intuition.h>
#include <graphics/view.h>
#include <graphics/gfxmacros.h>
#include <string.h>
#include <math.h>
#include <devices/audio.h>
#include <stdlib.h>
#define INTUITION_REV 0
#define GRAPHICS_REV 0
#define STATUSCON 0
#define STATUSHALT 1
#define STATUSGO 2
typedef struct{
ULONG oneShotHiSamples,repeatHiSamples,samplesPerHiCycle;
UWORD samplesPerSec;
UBYTE ctOctave,sCompression;
ULONG volume;
} Voice8Header;
extern struct IntuiMessage *GetMsg();
extern struct MsgPort *CreatePort();
extern struct Window *OpenWindow();
extern struct IntuitionBase *OpenLibrary();
extern struct Screen *OpenScreen();
extern char *pathcat();
extern void doparms();
extern void refwin();
extern void pr1();
extern void gadbox();
extern void clean();
extern int dism();
extern void fftlin();
extern int readin();
extern void findmark();
extern void putmark();
extern void playmark();
extern void timeline();
extern void distf();
extern long doiff();
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
struct IntuiText mn1i1t={0,1,JAM2,0,0,NULL,"About",NULL};
struct MenuItem mn1i1={NULL,0,8,100,8,
ITEMTEXT|ITEMENABLED|HIGHCOMP,
NULL,(APTR)&mn1i1t,NULL,NULL,NULL};
struct IntuiText mn1i0t={0,1,JAM2,0,0,NULL,"Restart",NULL};
struct MenuItem mn1i0={&mn1i1,0,0,100,8,
ITEMTEXT|ITEMENABLED|HIGHCOMP,
NULL,(APTR)&mn1i0t,NULL,NULL,NULL};
struct Menu mn1={NULL,100,0,100,0,
MENUENABLED,"Control",&mn1i0};
struct IntuiText mn0i1t={0,1,JAM2,0,0,NULL,"Quit",NULL};
struct MenuItem mn0i1={NULL,0,8,100,8,
ITEMTEXT|ITEMENABLED|HIGHCOMP,
NULL,(APTR)&mn0i1t,NULL,NULL,NULL};
struct IntuiText mn0i0t={0,1,JAM2,0,0,NULL,"Open",NULL};
struct MenuItem mn0i0={&mn0i1,0,0,100,8,
ITEMTEXT|ITEMENABLED|HIGHCOMP,
NULL,(APTR)&mn0i0t,NULL,NULL,NULL};
struct Menu mn0={&mn1,0,0,100,0,
MENUENABLED,"File",&mn0i0};
char gdundo[40];
float fa4=440.;
UBYTE gd31sb[]="440.0"; /* fa4 */
struct StringInfo gd31s={gd31sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
struct Gadget gd31={NULL,424,51,48,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd31s,31,NULL};
int gd30i=2;
char gd30s[5][2]={"1","3","5","7","9"};
struct IntuiText gd30gt={0,1,JAM2,0,0,NULL,&gd30s[2][0],NULL};
struct Gadget gd30={&gd31,432,101,8,8,
GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
&gd30gt,NULL,NULL,30,NULL};
int kdfpx=0;
int ndfpx=1,idfpx[8]={1,2,4,8,1,1,1,1};
int npxdf=1,ipxdf[8]={1,1,1,1,1,2,4,8};
char gd29s[8][5]={" 1 "," 2 "," 4 "," 8 "," 1 "," 1/2"," 1/4"," 1/8"};
struct IntuiText gd29gt={0,1,JAM2,0,0,NULL,&gd29s[0][0],NULL};
struct Gadget gd29={&gd30,368,41,32,8,
GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
&gd29gt,NULL,NULL,29,NULL};
UBYTE gd28sb[]=" 0"; /* ibt0 */
struct StringInfo gd28s={gd28sb,gdundo,0,9,0,0,0,0,0,0,0,0,0};
struct Gadget gd28={&gd29,312,11,72,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd28s,28,NULL};
UBYTE gd27sb[]=" 0"; /* ifp */
struct StringInfo gd27s={gd27sb,gdundo,0,9,0,0,0,0,0,0,0,0,0};
struct Gadget gd27={&gd28,496,11,72,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd27s,27,NULL};
UBYTE gd26sb[]=" 0.0"; /* colfrom */
struct StringInfo gd26s={gd26sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
struct Gadget gd26={&gd27,296,101,48,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd26s,26,NULL};
struct IntuiText gd25gt={0,1,JAM2,0,0,NULL," IFF",NULL};
struct Gadget gd25={&gd26,112,11,32,8,
GADGHCOMP,TOGGLESELECT|RELVERIFY,BOOLGADGET,NULL,NULL,
&gd25gt,NULL,NULL,25,NULL};
struct IntuiText gd24gt={0,1,JAM2,0,0,NULL," <-> ",NULL};
struct Gadget gd24={&gd25,152,11,40,8,
SELECTED|GADGHCOMP,TOGGLESELECT|RELVERIFY,BOOLGADGET,NULL,NULL,
&gd24gt,NULL,NULL,24,NULL};
struct IntuiText gd23gt={0,1,JAM2,0,0,NULL," RAW",NULL};
struct Gadget gd23={&gd24,200,11,32,8,
GADGHCOMP,TOGGLESELECT|RELVERIFY,BOOLGADGET,NULL,NULL,
&gd23gt,NULL,NULL,23,NULL};
char gd22s[2][5]={" NO "," YES"};
struct IntuiText gd22gt={0,1,JAM2,0,0,NULL,&gd22s[1][0],NULL};
struct Gadget gd22={&gd23,440,111,32,8,
GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
&gd22gt,NULL,NULL,22,NULL};
char gd21s[2][5]={" NO "," YES"};
struct IntuiText gd21gt={0,1,JAM2,0,0,NULL,&gd21s[1][0],NULL};
struct Gadget gd21={&gd22,248,111,32,8,
GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
&gd21gt,NULL,NULL,21,NULL};
char gd20s[2][4]={" % "," dB"};
struct IntuiText gd20gt={0,1,JAM2,0,0,NULL,&gd20s[1][0],NULL};
struct Gadget gd20={&gd21,216,101,24,8,
GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
&gd20gt,NULL,NULL,20,NULL};
UBYTE gd19sb[]=" 2.0"; /* colstep */
struct StringInfo gd19s={gd19sb,gdundo,0,5,0,0,0,0,0,0,0,0,0};
struct Gadget gd19={&gd20,168,101,40,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd19s,19,NULL};
UBYTE gd18sb[]="1.000";
struct StringInfo gd18s={gd18sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
struct Gadget gd18={&gd19,72,91,48,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd18s,18,NULL};
UBYTE gd17sb[]=" 2"; /* itani */
struct StringInfo gd17s={gd17sb,gdundo,0,3,0,0,0,0,0,0,0,0,0};
struct Gadget gd17={&gd18,168,81,24,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd17s,17,NULL};
UBYTE gd16sb[]=" 0.500"; /* tline */
struct StringInfo gd16s={gd16sb,gdundo,0,7,0,0,0,0,0,0,0,0,0};
struct Gadget gd16={&gd17,104,71,56,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd16s,16,NULL};
UBYTE gd15sb[]="0.500";
struct StringInfo gd15s={gd15sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
struct Gadget gd15={&gd16,96,61,48,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd15s,15,NULL};
SHORT gd14ird[]={0xffff,0xffff,0xc000,0x0003,
0xcfff,0xff03,0xcfff,0xff03,
0xcfff,0xfff3,0xcfc0,0x0033,
0xcfc0,0x0033,0xcfc0,0x0033,
0xcfc0,0x0033,0xcfc0,0x0033,
0xcfc0,0x0033,0xcfc0,0x0033,
0xc0c0,0x0033,0xc0ff,0xfff3,
0xc000,0x0003,0xffff,0xffff};
struct Image gd14ir={0,0,32,16,1,gd14ird, 1, 0,NULL};
struct Gadget gd14={&gd15,580,70,32,16,
GADGIMAGE|GADGHCOMP,RELVERIFY,
BOOLGADGET,(APTR)&gd14ir,NULL,NULL,NULL,NULL,14,NULL};
UBYTE gd13sb[]=" 4";
struct StringInfo gd13s={gd13sb,gdundo,0,3,0,0,0,0,0,0,0,0,0};
struct Gadget gd13={&gd14,168,51,24,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd13s,13,NULL};
UBYTE gd12sb[]="10";
struct StringInfo gd12s={gd12sb,gdundo,0,3,0,0,0,0,0,0,0,0,0};
struct Gadget gd12={&gd13,128,31,24,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd12s,12,NULL};
UBYTE gd11sb[]="10000";
struct StringInfo gd11s={gd11sb,gdundo,0,6,0,0,0,0,0,0,0,0,0};
struct Gadget gd11={&gd12,112,21,48,8,
GADGHCOMP,RELVERIFY,STRGADGET,NULL,NULL,
NULL,NULL,(APTR)&gd11s,11,NULL};
struct NewWindow nwin1={0,1,640,150,-1,-1,
NULL,
WINDOWCLOSE|SIMPLE_REFRESH|ACTIVATE|WINDOWDEPTH,
&gd11,NULL,"SeeHear",NULL,NULL,0,0,0,0,WBENCHSCREEN};
struct NewScreen nsc2={0,0,320,200,5,1,0,0,
CUSTOMSCREEN,NULL,"SCREEN",NULL,NULL};
SHORT gd4ird[]={0xffff,0x8001,0xbff1,0xbff1,
0xbffd,0xb805,0xb805,0xb805,
0xb805,0xb805,0xb805,0xb805,
0x8805,0x8ffd,0x8001,0xffff};
struct Image gd4ir={0,0,16,16,1,gd4ird, 1, 0,NULL};
struct Gadget gd4={NULL,290,70,16,16,
GADGIMAGE|GADGHCOMP,RELVERIFY,
BOOLGADGET,(APTR)&gd4ir,NULL,NULL,NULL,NULL,4,NULL};
SHORT gd3ird[]={0xc003,0x8001,0x0000,0x0300,
0x0600,0x0c00,0x7800,0xf000,
0xf000,0x7800,0x0c00,0x0600,
0x0300,0x0000,0x8001,0xc003,
0x0010,0x0008,0x0004,0x0024,
0x0012,0x0092,0x0049,0x0249,
0x0249,0x0049,0x0092,0x0012,
0x0024,0x0004,0x0008,0x0010};
struct Image gd3ir={0,0,16,16,1,gd3ird, 1, 0,NULL};
struct Image gd3is={0,0,16,16,2,gd3ird,12,16,NULL};
struct Gadget gd3={&gd4,290,40,16,16,
GADGHIMAGE|GADGIMAGE|GADGDISABLED,GADGIMMEDIATE,
BOOLGADGET,(APTR)&gd3ir,(APTR)&gd3is,NULL,NULL,NULL,3,NULL};
SHORT gd2isd[]={0x0000,0x07e0,0x0ff0,0x1ff8,
0x3ffc,0x7ffe,0x7ffe,0x7ffe,
0x7ffe,0x7ffe,0x7ffe,0x3ffc,
0x1ff8,0x0ff0,0x07e0,0x0000,
0x0000,0x07e0,0x0ff0,0x1ff8,
0x3ffc,0x7ffe,0x7ffe,0x7ffe,
0x7ffe,0x7ffe,0x7ffe,0x3ffc,
0x1ff8,0x0ff0,0x07e0,0x0000};
struct Image gd2is={0,0,16,16,5,gd2isd,9,0x12,NULL};
SHORT gd2ird[]={0x0000,0x0000,0x0280,0x0280,
0x3ff8,0x1450,0x2448,0x0440,
0x0820,0x0820,0x0820,0x1010,
0x1010,0x1010,0x0000,0x0000,
0x0000,0x0000,0x0280,0x0280,
0x3ff8,0x1450,0x2448,0x0440,
0x0820,0x0820,0x0820,0x1010,
0x1010,0x1010,0x0000,0x0000,
0x0000,0x0000,0x0280,0x0280,
0x3ff8,0x1450,0x2448,0x0440,
0x0820,0x0820,0x0820,0x1010,
0x1010,0x1010,0x0000,0x0000};
struct Image gd2ir={0,0,15,16,5,gd2ird,0xd,0x12,NULL};
struct Gadget gd2={&gd3,290,11,16,16,
GADGHIMAGE|GADGIMAGE|SELECTED,TOGGLESELECT|GADGIMMEDIATE,
BOOLGADGET,(APTR)&gd2is,(APTR)&gd2ir,NULL,NULL,NULL,2,NULL};
struct Image gd1ir;
struct PropInfo gd1p={AUTOKNOB|FREEVERT,0,0,-1,0x1100,0,0,0,0,0};
struct Gadget gd1={&gd2,308,21,11,176,
GADGHNONE|GADGIMAGE|GADGDISABLED,
RELVERIFY,PROPGADGET,(APTR)&gd1ir,NULL,NULL,NULL,
(APTR)&gd1p,1,NULL};
struct NewWindow nwn2={0,1,320,199,-1,-1,
NULL,
WINDOWCLOSE|SIMPLE_REFRESH|NOCAREREFRESH,
&gd1,NULL,"SeeHear",NULL,NULL,0,0,0,0,CUSTOMSCREEN};
UWORD colors[]={0x000,0x777,0x200,0x223,0x004,0x304,0x300,0x330,
0x030,0x035,0x334,0x335,0x436,0x423,0x443,0x343,
0x356,0x555,0x669,0x969,0x966,0x996,0x696,0x699,
0x999,0xaaf,0xfaf,0xfaa,0xffa,0xafa,0xaff,0xfff};
SHORT imdarrow[]={0x0200,0x0400,0x1800,0xff10,
0x1800,0x0400,0x0200,
0x0200,0x0400,0x1800,0xff10,
0x1800,0x0400,0x0200,
0x0200,0x0400,0x1800,0xff10,
0x1800,0x0400,0x0200,
0x0200,0x0400,0x1800,0xff10,
0x1800,0x0400,0x0200,
0x0200,0x0400,0x1800,0xff10,
0x1800,0x0400,0x0200};
int pky[12]={31,0,31,31,0,31,0,31,31,0,31,0};
char *cky[12]={"A","A#","B","C","C#","D","D#","E","F","F#","G","G#"};
struct MsgPort *mprt=NULL;
struct Screen *scr2=NULL;
struct Window *win1=NULL,*win2=NULL;
struct RastPort *rp1=NULL,*rp2=NULL;
struct Image imarrow={0,0,9,7,5,imdarrow,1,0,NULL};
struct ViewPort *vp2;
struct IntuiMessage *msg;
FILE *fp=NULL;
TEXT filen[34],dirn[67],pathn[100];
int ie,line,linf=21,i2fft=10,nfft=1024,istep=512,jdt,imark=3,itser;
int lmark[4],itani=2,nseries=0,ifani=4,npix=256,linl=198;
int go=FALSE,plin=1,pbefore=1,quitnow=0,readit=FALSE;
int status=-1,dbflag=1,kkeep=0,markf=0,setoff=0;
char *series=NULL,*sound=NULL,*ps,prt[82];
float *fseries=NULL,*smooth=NULL,cut[32],ai,ri,si,*pf;
float srate=10000.,dt=.0001,tstep,tline=0.5,tser,df,dfpx,cint=279.365e-9;
float fani=400.,tstepf=.5,smwid=1.,smsum,colstep=2.,colfrom=0.;
long iser=0,ibt0=0,ifp=0,nfp=0,nsnd=0,msnd;
struct Gadget *pgdt;
Voice8Header vhdr;
void main()
{
static struct IntuiText rq3bt3={0,1,JAM2,6,29,NULL,
"SeeHear, version 1.1, 1990-03-11",NULL};
static struct IntuiText rq3bt2={0,1,JAM2,6,21,NULL,
"Freely distributable for non-commercial use.",&rq3bt3};
static struct IntuiText rq3bt1={0,1,JAM2,6,11,NULL,
"2654 E. 26 St., Tulsa, OK 74114",&rq3bt2};
static struct IntuiText rq3bt={0,1,JAM2,6,3,NULL,
"Copyright 1990 by Daniel T. Johnson",&rq3bt1};
static struct IntuiText rq3nt={0,1,JAM2,6,3,NULL,"Continue",NULL};
static struct IntuiText *cit;
static USHORT nmen,numm,numi;
si=exp(2./3.); /* force load of ffp library */
cit=&rq3bt;
while(cit){
printf("%s\n",cit->IText);
cit=cit->NextText;
}
df=srate/nfft;
dfpx=df;
msnd=nfft+istep*(198-linf);
IntuitionBase=OpenLibrary("intuition.library",INTUITION_REV);
if(IntuitionBase==NULL) dism("IntuitionBase",0);
GfxBase=(struct GfxBase *)OpenLibrary("graphics.library", GRAPHICS_REV);
if(GfxBase==NULL) dism("GfxBase",0);
if((mprt=CreatePort(NULL,0))==NULL) dism("mprt",0);
if((scr2=OpenScreen(&nsc2))==NULL) dism("OpenScreen",0);
ScreenToBack(scr2);
vp2=&(scr2->ViewPort);
LoadRGB4(vp2,colors,32);
nwn2.Screen=scr2;
if((win2=OpenWindow(&nwn2))==NULL)
dism("OpenWindow",0);
win2->UserPort=mprt;
ModifyIDCMP(win2,MOUSEBUTTONS|GADGETDOWN|GADGETUP|CLOSEWINDOW|MENUPICK);
rp2=win2->RPort;
OpenWorkBench();
if((win1=OpenWindow(&nwin1))==NULL) dism("OpenWindow",0);
win1->UserPort=mprt;
ModifyIDCMP(win1,GADGETUP|MENUPICK|REFRESHWINDOW|CLOSEWINDOW);
rp1=win1->RPort;
filen[0]=0;dirn[0]=0;
setstatus(STATUSCON);
refwin();
dism("menu File/Open to start; adjust parameters first if needed",1);
/*Main user interaction loop*/
for(;;){
if(!readit) go=FALSE;
if((msg=(struct IntuiMessage *)GetMsg(mprt))==NULL){
if(status==STATUSGO) fftlin();
else WaitPort(win2->UserPort);
}else{
switch(msg->Class){
case REFRESHWINDOW:
BeginRefresh(win1);
refwin();
EndRefresh(win1);
break;
case CLOSEWINDOW:
clean();
case GADGETDOWN:
distf(0);
pgdt=(struct Gadget *)msg->IAddress;
switch(pgdt->GadgetID){
case 2:
if(pgdt->Flags&SELECTED) setstatus(STATUSGO);
else setstatus(STATUSHALT);
break;
case 3:
pgdt->Flags|=SELECTED;
RefreshGadgets(&gd3,win2,NULL);
playmark();
pgdt->Flags^=SELECTED;
RefreshGadgets(&gd3,win2,NULL);
break;
}
break;
case GADGETUP:
distf(0);
pgdt=(struct Gadget *)msg->IAddress;
switch(pgdt->GadgetID){
case 1:
ifp=nfp*(gd1p.VertPot/65535.);
if(ifp>(nfp-nfft)) ifp=nfp-nfft;
if(fp) readin(); /*wipes out msg*/
setstatus(STATUSGO);
break;
case 4: /*flip to WB*/
setstatus(STATUSCON);
break;
case 14: /*flip to scr2*/
setstatus(STATUSHALT);
break;
default:
doparms();
}
break;
case MOUSEBUTTONS:
distf(0);
if(go) break;
switch(msg->Code){
case SELECTDOWN:
findmark();
break;
case SELECTUP:
putmark(1);
break;
}
break;
case MENUPICK:
nmen=msg->Code;
numm=MENUNUM(nmen);
numi=ITEMNUM(nmen);
switch(numm){
case 0:
switch(numi){
case 0: /*Open*/
/* Charlie Heath file requester from Fred Fish library
AmigaLibDisk35:FileRequester/getfil.o */
if(!get_fname(win1,"SeeHear input file",filen,dirn)) break;
if(fp) fclose(fp);
readit=FALSE;
if(!pathcat(pathn,dirn,filen)) break;
if((fp=fopen(pathn,"r"))==NULL){
dism("Can't open file - try again",1);
break;
}
fseek(fp,0,2);
nfp=ftell(fp);
rewind(fp);
if(nfp<nfft){
fclose(fp);fp=NULL;
dism("Input file short - try again",2);
}
dism("Reading input file",1);
if(!setoff){
ifp=0;
ibt0=0;
}
if(!readin()) break;
dism("SeeHear analysis underway",1);
setstatus(STATUSGO);
break;
case 1: /*Quit*/
clean();
break;
}
break;
case 1:
switch(numi){
case 0: /*Restart*/
if(!fp){
dism("must Open a File first",1);
break;
}
dism("Reading input file",1);
if(!readin()) break;
dism("SeeHear analysis underway",1);
setstatus(STATUSGO);
break;
case 1:
AutoRequest(win1,&rq3bt,NULL,&rq3nt,0,0,400,100);
break;
}
break;
}
break;
}
ReplyMsg(msg);
}
}
}
/**************************************/
void clean()
{
if(series) fftcr(series,0);
if(fp) fclose(fp);
if(win2){
win2->UserPort=NULL;
CloseWindow(win2);
}
if(win1){
win1->UserPort=NULL;
CloseWindow(win1);
}
if(mprt){
DeletePort(mprt);
}
if(scr2) CloseScreen(scr2);
if(fseries) free((char *)fseries);
if(smooth) free((char *)smooth);
if(series) FreeMem(series,nseries);
if(sound) FreeMem(sound,nsnd);
exit(0);
}
/**************************************/
void fftlin()
{
register short i,j,k,l;
if((iser+nfft)>nsnd) setstatus(STATUSHALT);
if(line>198) setstatus(STATUSHALT);
if(status!=STATUSGO) return;
for(ps=sound+iser,i=0;i<nfft;++i,++ps){
series[i]=fseries[i]=smooth[i]*(*ps);
}
fftcr(fseries,i2fft);
for(pf=fseries,i=0;i<npix;i+=npxdf){
if(ndfpx>1){
for(j=0,ai=0.;j<ndfpx;++j){
ri=*pf++;
si=*pf++;
ai+=(ri*ri+si*si);
}
ai/=ndfpx;
}else{
ri=*pf++;
si=*pf++;
ai=(ri*ri+si*si);
}
for(j=16,k=0,l=j;j;j>>=1,l=k|j) if(ai>cut[l]) k=l;
if(k<2) k=2;
SetAPen(rp2,k);
for(j=0;j<npxdf;++j){
WritePixel(rp2,18+i+j,line);
}
}
if(plin) play(series,nfft,jdt);
if(tser>=tline){
++itser;
timeline();
tser=tser-tline;
}
tser+=tstep;
iser+=istep;
++line;
}
/**************************************/
int readin()
{
static int i,j,k;
static float f;
setstatus(STATUSCON);
readit=FALSE;
if(!fp){
dism("must Open a File first",1);
return(FALSE);
}
if(series) FreeMem(series,nseries);
if((series=(char *)AllocMem(nfft,MEMF_CHIP|MEMF_CLEAR))==NULL)
dism("AllocMem series",0);
nseries=nfft;
if(fseries) free((char *)fseries);
if((fseries=(float *)calloc(nfft,4))==NULL)
dism("calloc fseries",0);
if(smooth) free((char *)smooth);
if((smooth=(float *)calloc(nfft,4))==NULL)
dism("calloc smooth",0);
if(sound) FreeMem(sound,nsnd);
sound=NULL;
msnd=nfft+istep*(198-linf);
SetDrMd(rp2,JAM1);
BNDRYOFF(rp2);
SetAPen(rp2,0);
RectFill(rp2,0,10,274,198);
kkeep=0;
SetAPen(rp2,1);
RectFill(rp2,18,linf,273,198);
for(k=0,f=fa4/8.,j=0;j<256;f*=1.0594631,k=(k+1)%12){
j=.5+f/dfpx;
SetAPen(rp2,pky[k]);
if(3<j&&j<253){
RectFill(rp2,j+18,linf-2,j+18,189);
Move(rp2,j+15,197-8*k);
Text(rp2,cky[k],strlen(cky[k]));
}
}
for(k=291,i=2;k<306;k+=8)
for(j=90;j<180;++i,j+=6){
SetAPen(rp2,i);
RectFill(rp2,k,j,k+5,j+5);
}
dt=1./srate;
jdt=dt/cint;
df=1./(dt*nfft);
dfpx=ndfpx*df/npxdf;
npix=(nfft*npxdf)/(2*ndfpx);
if(npix>256) npix=256;
tstep=istep*dt;
if(gd23.Flags&SELECTED){
fseek(fp,0,2);
nfp=ftell(fp)-ibt0;
}else{
if(ibt0=doiff(&vhdr,fp)){
nfp=vhdr.oneShotHiSamples;
srate=i=vhdr.samplesPerSec;
dt=1./srate;
jdt=dt/cint;
sprintf(gd11sb,"%5d",i);
if(gd24.Flags&SELECTED){
gd25.Flags|=SELECTED;
gd24.Flags&=~SELECTED;
gd23.Flags&=~SELECTED;
}
RefreshGadgets(&gd11,win1,NULL);
refwin();
}else{
dism("not IFF, doing RAW",1);
gd23.Flags|=SELECTED;
gd24.Flags&=~SELECTED;
gd25.Flags&=~SELECTED;
}
}
if(ifp>(nfp-nfft)) ifp=nfp-nfft;
if(nfp>msnd) gd1p.VertBody=(61440.*msnd)/nfp;
else gd1p.VertBody=61440;
gd1p.VertPot=(65535.*ifp)/nfp;
sprintf(gd27sb,"%8ld",ifp);
sprintf(gd28sb,"%8ld",ibt0);
RefreshGadgets(&gd27,win1,NULL);
iser=0;
tser=ifp*dt/tline;
itser=tser;
tser=ifp*dt-itser*tline;
j=nfft/2;
f=smwid*istep*.5;
for(i=0,smsum=0.;i<nfft;++i){
ri=(i-j)/f;
smsum+=smooth[i]=exp(-ri*ri);
}
if(dbflag){
si=pow(10.,(-colstep/10.));
ri=128.*smsum*pow(10.,(colfrom/20.));
ri=ri*ri*si;
for(i=31;i>=0;--i,ri*=si) cut[i]=ri;
}else{
ri=128.*smsum;
si=ri*colstep/100.;
ri=ri*colfrom/100.;
ri-=si;
for(i=31;i>=0;--i,ri-=si){
if(ri>0) cut[i]=ri*ri;
else cut[i]=cut[i+1];
}
}
fseek(fp,ibt0+ifp,0);
nsnd=nfp-ifp;
if(nsnd>msnd) nsnd=msnd;
if(nsnd<nfft) dism("file short - Open another",1);
if((sound=(char *)AllocMem(nsnd,MEMF_CHIP|MEMF_CLEAR))==NULL)
dism("AllocMem sound",0);
if(fread(sound,1,nsnd,fp)!=nsnd) dism("file length trouble",1);
line=linf-1;
timeline();
line=linf;
imark=3;
lmark[3]=linf;
linl=linf+(nsnd-nfft)/istep;
lmark[1]=linl;
lmark[2]=(lmark[1]+lmark[3])/2;
putmark(0);
if(pbefore) playmark();
SetAPen(rp2,1);
for(f=0.,i=0;i<256;i=.5+(f+=fani)/dfpx){
j=.5+f/100.;
sprintf(prt,"%2d\0",j);
Move(rp2,i+6,18);
Text(rp2,prt,2);
}
readit=TRUE;
setoff=FALSE;
return(TRUE);
}
/**************************************/
void findmark()
{
register int i;
for(i=3;i;--i){
if(msg->MouseX>=275&&
msg->MouseX<=283&&
msg->MouseY>=lmark[i]-3&&
msg->MouseY<=lmark[i]+3) break;
}
imark=i;
if(imark){
imarrow.PlanePick=27;
DrawImage(rp2,&imarrow,275,lmark[imark]-3);
markf=1;
}
return;
}
/**************************************/
void putmark(ifm)
int ifm;
{
register int i;
if(imark&&
ifm&&
msg->MouseX>=18&&
msg->MouseX<=273&&
msg->MouseY>=linf&&
msg->MouseY<=linl) lmark[imark]=msg->MouseY;
switch(imark){
case 1:
if(lmark[2]>lmark[1]) lmark[2]=lmark[1];
if(lmark[3]>lmark[1]) lmark[3]=lmark[1];
break;
case 2:
if(lmark[1]<lmark[2]) lmark[1]=lmark[2];
if(lmark[3]>lmark[2]) lmark[3]=lmark[2];
if(markf) distf(msg->MouseX);
else distf(0);
break;
case 3:
if(lmark[1]<lmark[3]) lmark[1]=lmark[3];
if(lmark[2]<lmark[3]) lmark[2]=lmark[3];
break;
}
SetAPen(rp2,0);
RectFill(rp2,275,linf-3,283,198);
for(i=1;i<=3;++i){
if(i==imark) imarrow.PlanePick=29;
else imarrow.PlanePick=1;
DrawImage(rp2,&imarrow,275,lmark[i]-3);
}
markf=0;
return;
}
/**************************************/
void playmark()
{
static FILE *tout=NULL;
register long i,j;
static long *kser=NULL;
static SHORT blip[]={0x7f81,0x7f81,0x7f81,0x7f81,
0x7f81,0x7f81,0x7f81,0x7f81};
switch(imark){
case 1:
i=istep*(lmark[3]-linf);
j=istep*(lmark[2]-lmark[3]);
if(j>0) play(sound+i,j,jdt);
i+=j;
play(blip,16,jdt);
play(sound+i,nfft,jdt);
play(blip,16,jdt);
i+=nfft;
j=nfft+istep*(lmark[1]-linf)-i;
if(j>0) play(sound+i,j,jdt);
break;
case 2:
tout=fopen("ram:SeeHear.temp","w");
kser=(long *)fseries;
kser[0]=i2fft;kser[1]=nfft;
if(tout) fwrite((char *)kser,4,2,tout);
ps=sound+istep*(lmark[2]-linf);
for(i=0;i<nfft;++i,++ps) kser[i]=*ps;
if(tout) fwrite((char *)kser,4,nfft,tout);
ps=sound+istep*(lmark[2]-linf);
for(i=0;i<nfft;++i,++ps) series[i]=kser[i]=smooth[i]*(*ps);
if(tout) fwrite((char *)kser,4,nfft,tout);
play(series,nfft,jdt);
for(i=0;i<nfft;++i) fseries[i]=series[i];
fftcr(fseries,i2fft);
for(i=0;i<nfft;++i) kser[i]=fseries[i];
if(tout) fwrite((char *)kser,4,nfft,tout);
if(tout) fclose(tout);
break;
case 3:
i=istep*(lmark[3]-linf);
j=nfft+istep*(lmark[1]-lmark[3]);
play(sound+i,j,jdt);
break;
default:
play(sound,nsnd,jdt);
}
return;
}
/**************************************************/
void timeline()
{
register short i;
static float f;
SetAPen(rp2,27);
for(f=0.,i=0;i<256;i=.5+(f+=fani)/dfpx) WritePixel(rp2,i+18,line);
if(fani/dfpx>7.5){
SetAPen(rp2,22);
for(f=fani/2.,i=.5+f/dfpx;i<256;i=.5+(f+=fani)/dfpx)
WritePixel(rp2,i+18,line);
}
if(fani/dfpx>15.5){
SetAPen(rp2,18);
for(f=fani/4.,i=.5+f/dfpx;i<256;i=.5+(f+=fani/2.)/dfpx)
WritePixel(rp2,i+18,line);
}
if(!(itser%itani)){
SetAPen(rp2,1);
i=.5+itser*tline;
sprintf(prt,"%2d",i);
Move(rp2,0,line+3);
Text(rp2,prt,2);
WritePixel(rp2,17,line);
}
}
/****************************************************/
int dism(dmes,dk)
char *dmes;
int dk;
{
static struct IntuiText rq1bt={0,1,JAM2,6,3,NULL,"Warning",NULL};
static struct IntuiText rq2bt={0,1,JAM2,6,3,NULL,"ERROR",NULL};
static struct IntuiText rq1pt={0,1,JAM2,6,3,NULL,"Continue",NULL};
static struct IntuiText rq1nt={0,1,JAM2,6,3,NULL,"Quit",NULL};
setstatus(STATUSCON);
SetAPen(rp1,0);
RectFill(rp1,4,125,635,148);
SetAPen(rp1,1);
Move(rp1,16,135);
Text(rp1,dmes,strlen(dmes));
if(dk==0){
Move(rp1,100,147);
SetAPen(rp1,3);
Text(rp1,"FATAL ERROR - must exit",23);
AutoRequest(win1,&rq2bt,NULL,&rq1nt,0,0,250,50);
clean();
}else if(dk==2){
if(AutoRequest(win1,&rq1bt,&rq1pt,&rq1nt,0,0,250,50));
else clean();
}
return(dk);
}
/************************************************/
char *pathcat(pcpn,pcdn,pcfn)
char *pcpn,*pcdn,*pcfn;
{
static int i;
static char pcc=':';
i=strlen(pcdn);
if(i<1){
strncpy(pcpn,pcfn,30);
}else{
strncpy(pcpn,pcdn,60);
if(pcdn[i-1]!=pcc) strcat(pcpn,"/");
strncat(pcpn,pcfn,30);
}
if(strlen(pcpn)<1) return(NULL);
else return(pcpn);
}
/***********************************************/
void doparms()
{
static int i;
switch(pgdt->GadgetID){
case 11:
sscanf(gd11sb,"%f",&srate);
i=srate;
if(i<1000) i=1000;
if(i>27000) i=27000;
srate=i;
dt=1./srate;
jdt=dt/cint;
sprintf(gd11sb,"%5d",i);
readit=FALSE;
break;
case 12:
sscanf(gd12sb,"%d",&i2fft);
if(i2fft<6) i2fft=6;
if(i2fft>14) i2fft=14;
sprintf(gd12sb,"%2d",i2fft);
for(nfft=64,i=6;i<i2fft;++i) nfft+=nfft;
istep=tstepf*nfft;
if(istep<1) istep=1;
if(istep>(16*nfft)) istep=16*nfft;
tstepf=(istep+0.)/nfft;
sprintf(gd15sb,"%5.3f",tstepf);
if(i2fft<=5) kdfpx=7;
else if(i2fft<=8) kdfpx=13-i2fft;
else if(i2fft<=10) kdfpx=0;
else if(i2fft<=13) kdfpx=i2fft-10;
else kdfpx=3;
gd29gt.IText=(UBYTE *)gd29s[kdfpx];
ndfpx=idfpx[kdfpx];
npxdf=ipxdf[kdfpx];
readit=FALSE;
break;
case 13:
sscanf(gd13sb,"%d",&ifani);
if(ifani<1) ifani=1;
if(ifani>80) ifani=80;
sprintf(gd13sb,"%2d",ifani);
fani=100*ifani;
break;
case 15:
sscanf(gd15sb,"%f",&tstepf);
istep=tstepf*nfft;
if(istep<1) istep=1;
if(istep>(16*nfft)) istep=16*nfft;
tstepf=(istep+0.)/nfft;
sprintf(gd15sb,"%5.3f",tstepf);
readit=FALSE;
break;
case 16:
sscanf(gd16sb,"%f",&tline);
if(tline<.001) tline=.001;
i=tline/(dt*istep);
if(i<4) tline=4*istep*dt;
if(tline>99.) tline=99.;
sprintf(gd16sb,"%6.3f",tline);
break;
case 17:
sscanf(gd17sb,"%d",&itani);
if(itani<1) itani=1;
if(itani>99) itani=99;
sprintf(gd17sb,"%2d",itani);
break;
case 18:
sscanf(gd18sb,"%f",&smwid);
if(smwid<=.01) smwid=.01;
if(smwid>99.) smwid=99.;
sprintf(gd18sb,"%5.2f",smwid);
readit=FALSE;
break;
case 19:
sscanf(gd19sb,"%f",&colstep);
if(colstep<.1) colstep=.1;
if(colstep>99.) colstep=99.;
sprintf(gd19sb,"%4.1f",colstep);
readit=FALSE;
break;
case 20:
dbflag=(dbflag+1)%2;
gd20gt.IText=(UBYTE *)gd20s[dbflag];
readit=FALSE;
break;
case 21:
pbefore=(pbefore+1)%2;
gd21gt.IText=(UBYTE *)gd21s[pbefore];
break;
case 22:
plin=(plin+1)%2;
gd22gt.IText=(UBYTE *)gd22s[plin];
break;
case 23:
gd23.Flags|=SELECTED;
gd24.Flags&=~SELECTED;
gd25.Flags&=~SELECTED;
break;
case 24:
gd24.Flags|=SELECTED;
gd23.Flags&=~SELECTED;
gd25.Flags&=~SELECTED;
break;
case 25:
gd25.Flags|=SELECTED;
gd23.Flags&=~SELECTED;
gd24.Flags&=~SELECTED;
break;
case 26:
sscanf(gd26sb,"%f",&colfrom);
if(dbflag){
if(colfrom>99.) colfrom=99.;
if(colfrom<-99.) colfrom=-99.;
}else{
if(colfrom>999.) colfrom=999.;
if(colfrom<0.) colfrom=0.;
}
sprintf(gd26sb,"%5.1f",colfrom);
break;
case 27:
sscanf(gd27sb,"%ld",&ifp);
if(ifp<0) ifp=0;
sprintf(gd27sb,"%8ld",ifp);
readit=FALSE;
setoff=TRUE;
break;
case 28:
sscanf(gd28sb,"%ld",&ibt0);
if(ibt0<0) ibt0=0;
sprintf(gd28sb,"%8ld",ibt0);
readit=FALSE;
setoff=TRUE;
break;
case 29:
kdfpx=(kdfpx+1)%8;
gd29gt.IText=(UBYTE *)gd29s[kdfpx];
ndfpx=idfpx[kdfpx];
npxdf=ipxdf[kdfpx];
break;
case 30:
gd30i=(gd30i+1)%5;
gd30gt.IText=(UBYTE *)gd30s[gd30i];
break;
case 31:
sscanf(gd31sb,"%f",&fa4);
if(fa4<220.) fa4=220.;
if(fa4>880.) fa4=880.;
sprintf(gd31sb,"%5.1f",fa4);
break;
}
dt=1./srate;
jdt=dt/cint;
df=1./(dt*nfft);
dfpx=ndfpx*df/npxdf;
tstep=istep*dt;
iser=0;
tser=ifp*dt/tline;
itser=tser;
tser=ifp*dt-itser*tline;
RefreshGadgets(&gd11,win1,NULL);
refwin();
}
/******************************************/
void refwin()
{
pr1(16,17,"File format");
gadbox(112,17,15);
pr1(248,17,"t0 byte");
gadbox(312,17,9);
pr1(392,17,"start offset");
gadbox(496,17,9);
pr1(16,27,"Sample rate");
gadbox(112,27,6);
sprintf(prt,"Hz; interval%8.3f us",(1.e6/srate));
pr1(168,27,prt);
sprintf(prt,"%8d samples",nfp);
pr1(400,27,prt);
pr1(16,37,"FFT length 2^");
gadbox(128,37,3);
sprintf(prt,"=%5d samples;%8.3f ms time slice",
nfft,(nfft*1.e3/srate));
pr1(160,37,prt);
sprintf(prt,"frequency step%6.2f Hz %6.2f Hz/pixel",df,dfpx);
pr1(48,47,prt);
gadbox(368,47,4);
pr1(408,47,"steps/pixel");
pr1(16,57,"Frequency annotate");
gadbox(168,57,3);
sprintf(prt,"hundred Hz;%5.1f pixels",(fani/dfpx));
pr1(200,57,prt);
pr1(400,57,"A=");
gadbox(424,57,6);
pr1(480,57,"Hz");
pr1(16,67,"Time step");
gadbox(96,67,6);
sprintf(prt,"of FFT; %5d samples;%8.3f ms",istep,(istep*1.e3/srate));
pr1(152,67,prt);
pr1(16,77,"Time lines");
gadbox(104,77,7);
sprintf(prt,"s =%5.1f pixels (time steps)",(tline/(dt*istep)));
pr1(168,77,prt);
pr1(48,87,"annotate every");
gadbox(168,87,3);
sprintf(prt,"time lines =%5.1f pixels",(itani*tline/(dt*istep)));
pr1(200,87,prt);
pr1(16,97,"Smooth");
gadbox(72,97,6);
sprintf(prt,"of time step = %5.3f of FFT =%8.3f ms",(tstepf*smwid),
(smwid*istep*1.e3/srate));
pr1(128,97,prt);
pr1(16,107,"Color change every");
gadbox(168,107,5);
gadbox(216,107,3);
pr1(248,107,"below");
gadbox(296,107,6);
pr1(352,107,"Peak seek");
gadbox(432,107,1);
pr1(448,107,"pixels");
pr1(16,117,"Play sound before analysis?");
gadbox(248,117,4);
pr1(296,117,"during analysis?");
gadbox(440,117,4);
}
/******************************************/
void gadbox(x,y,n)
int x,y,n;
{
int xa,xb,ya,yb;
xa=x-1;xb=x+8*n;ya=y-7;yb=y+2;
SetAPen(rp1,3);
Move(rp1,xa,ya);
Draw(rp1,xb,ya);
Draw(rp1,xb,yb);
Draw(rp1,xa,yb);
Draw(rp1,xa,ya);
SetAPen(rp1,1);
}
/******************************************/
void pr1(x,y,s)
int x,y;
char *s;
{
SetAPen(rp1,1);
Move(rp1,x,y);
Text(rp1,s,strlen(s));
}
/******************************************/
int setstatus(newstat)
int newstat;
{
switch(newstat){
case STATUSCON:
for(pgdt=win2->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
if(!(pgdt->Flags&GADGDISABLED)) OffGadget(pgdt,win2,NULL);
OnGadget(&gd4,win2,NULL);
gd2.Flags|=SELECTED;
gd2.Flags^=SELECTED;
RefreshGadgets(&gd1,win2,NULL);
WBenchToFront();
/* WindowToFront(win1); */
SetMenuStrip(win1,&mn0);
for(pgdt=win1->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
if(pgdt->Flags&GADGDISABLED) OnGadget(pgdt,win1,NULL);
status=STATUSCON;
return(TRUE);
case STATUSHALT:
if(status==STATUSCON){
for(pgdt=win1->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
if(!(pgdt->Flags&GADGDISABLED)) OffGadget(pgdt,win1,NULL);
OnGadget(&gd14,win1,NULL);
RefreshGadgets(&gd11,win1,NULL);
ClearMenuStrip(win1);
}
ScreenToFront(scr2);
for(pgdt=win2->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
if(pgdt->Flags&GADGDISABLED) OnGadget(pgdt,win2,NULL);
gd2.Flags|=SELECTED;
gd2.Flags^=SELECTED;
RefreshGadgets(&gd1,win2,NULL);
status=STATUSHALT;
return(TRUE);
case STATUSGO:
if(!readit){
return(FALSE);
}
if(status==STATUSCON){
for(pgdt=win1->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
if(!(pgdt->Flags&GADGDISABLED)) OffGadget(pgdt,win1,NULL);
OnGadget(&gd14,win1,NULL);
RefreshGadgets(&gd11,win1,NULL);
ClearMenuStrip(win1);
ScreenToFront(scr2);
for(pgdt=win2->FirstGadget;pgdt;pgdt=pgdt->NextGadget)
if(pgdt->Flags&GADGDISABLED) OnGadget(pgdt,win2,NULL);
}
OffGadget(&gd1,win2,NULL);
OffGadget(&gd3,win2,NULL);
gd2.Flags|=SELECTED;
RefreshGadgets(&gd1,win2,NULL);
status=STATUSGO;
return(TRUE);
default:
dism("Status error",0);
}
return(FALSE);
}
/******************************************/
long doiff(v,p)
Voice8Header *v;
FILE *p;
{
long *k,ip;
char cf[12];
k=(long *)(cf+4);
rewind(p);
if(fread(cf,1,12,p)<12) return(0);
if(strncmp(cf,"FORM",4)) return(0);
if(strncmp(cf+8,"8SVX",4)) return(0);
if(fread(cf,1,8,p)<8) return(0);
if(strncmp(cf,"VHDR",4)) return(0);
if(fread((char *)v,1,20,p)<20) return(0);
ip=12;
while(strncmp(cf,"BODY",4)) {
ip+=(*k+8);
if(fseek(p,ip,0)) return(0);
if(fread(cf,1,8,p)<8) return(0);
}
return(ip+8);
}
/***********************************************/
void distf(ii)
int ii;
{
static float t,f,fl,y0,y1,y2,r;
static char ckeep[20],*ckp;
static int i,is,ifl,j,k,k0,k1,k2;
if(ii){
t=dt*(ifp+istep*(lmark[2]-linf)+nfft/2);
j=lmark[2];
k0=0;
for(is=ii-gd30i;is<=ii+gd30i;++is){
k=is;
if(k<18) k=18;
if(k>273) k=273;
k1=ReadPixel(rp2,k,j);
if(k1>k0) {i=k;k0=k1;}
}
k=i-npxdf;if(k<18) k=18;
k1=ReadPixel(rp2,k,j);if(k1>k0) k1=k0;
k=i+npxdf;if(k>273) k=273;
k2=ReadPixel(rp2,k,j);if(k2>k0) k2=k0;
if(k1<k2){
k=k1;k1=k2;k2=k;
k=1;
}else if(k1>k2) k=-1;
else k=0;
if(k&&gd30i){
y0=log(cut[k0]);
y1=log(cut[k1]);
y2=log(cut[k2]);
if(y0>y2) r=(y0-y1)/(y0-y2);
else r=1.;
r=k*(1.-r)/(2.*r+2.);
}else r=0.;
f=dfpx*(i+r-18);
if(f<1.) f=1.;
fl=120.+17.31234*(log(f)-log(fa4));
ifl=fl+.5;
fl=fl-ifl;
SetAPen(rp2,0);
RectFill(rp2,74,0,319,8);
SetAPen(rp2,1);
kkeep=i;
k=ReadPixel(rp2,i,j);
sprintf(prt,"%5.2f s %5.0f Hz %s%+4.2f %d\0",t,f,cky[ifl%12],fl,k);
Move(rp2,74,7);
Text(rp2,prt,strlen(prt));
SetAPen(rp2,0);
for(k=2,ckp=ckeep;k<4;++k){
*ckp++=ReadPixel(rp2,kkeep+k,j);
WritePixel(rp2,kkeep+k,j);
*ckp++=ReadPixel(rp2,kkeep,j+k);
WritePixel(rp2,kkeep,j+k);
*ckp++=ReadPixel(rp2,kkeep-k,j);
WritePixel(rp2,kkeep-k,j);
*ckp++=ReadPixel(rp2,kkeep,j-k);
WritePixel(rp2,kkeep,j-k);
}
for(j=-1;j<=1;++j)
for(k=-1;k<=1;++k){
SetAPen(rp2,ReadPixel(rp2,kkeep+j*npxdf,lmark[2]+k*npxdf));
RectFill(rp2,314+3*j,3+3*k,316+3*j,5+3*k);
}
k=ReadPixel(rp2,kkeep,lmark[2]);
SetAPen(rp2,k);
k=90+6*(k-2);
if(k>174) {k-=90;j=298;}
else j=290;
if(k>89) RectFill(rp2,j,k,j,k+5);
if(k>89) RectFill(rp2,j+7,k,j+7,k+5);
k=ReadPixel(rp2,kkeep-npxdf,lmark[2]);
SetAPen(rp2,k);
k=90+6*(k-2);
if(k>174) {k-=90;j=298;}
else j=290;
if(k>89) RectFill(rp2,j,k,j,k+5);
k=ReadPixel(rp2,kkeep+npxdf,lmark[2]);
SetAPen(rp2,k);
k=90+6*(k-2);
if(k>174) {k-=90;j=298;}
else j=290;
if(k>89) RectFill(rp2,j+7,k,j+7,k+5);
}else if(kkeep){
j=lmark[2];
for(k=2,ckp=ckeep;k<4;++k){
SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep+k,j);
SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep,j+k);
SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep-k,j);
SetAPen(rp2,*ckp++);WritePixel(rp2,kkeep,j-k);
}
SetAPen(rp2,0);
RectFill(rp2,74,0,319,8);
RectFill(rp2,290,90,290,179);
RectFill(rp2,297,90,298,179);
RectFill(rp2,305,90,305,179);
}
}
/*******************************************************************/
/* fast fourier transform subroutine */
int fftcr(x,nt)
float *x;
int nt;
{
static short *mf=NULL,nb,ib,na,n2a,n4a,ia,ie;
static int ne,nf,ns,ntp=-1;
register short i,j,k,l;
static float *sine=NULL,rk,sk,fr,fs,gr,gs,hr,hs;
register float *ri,*si,*rh,*sh;
static double pi,w,dw;
if(nt!=ntp){
pi=4.*atan(1.);
ntp=0;
if(mf) free((char *)mf);
if(sine) free((char *)sine);
if(nt<4||nt>16) return(4);
ne=nt-1;
for(i=1,ns=1;i<ne;++i) ns+=ns;
nf=ns+ns;
if((mf=(short *)calloc(2,nf))==NULL) return(1);
if((sine=(float *)calloc(4,ns+1))==NULL) return(2);
sine[0]=0.;
dw=-pi/nf;
for(i=1,w=dw;i<ns;++i,w+=dw)
sine[i]=sin(w);
sine[ns]=-1.;
for(k=0;k<nf;++k){
for(i=ns,j=1,l=0;i;i>>=1,j<<=1)
if(j&k) l|=i;
mf[k]=l;
}
ntp=nt;
}
na=ns;n2a=nf;n4a=4*na;
nb=1;
for(ie=0;ie<ne;++ie){
for(ib=0,i=0;ib<nb;++ib,i+=n4a){
k=mf[ib];
if(k>ns){
rk=sine[k-ns];
sk=sine[nf-k];
}
else{
rk=-sine[ns-k];
sk=sine[k];
}
ri=x+i;
si=ri+1;
rh=ri+n2a;
sh=rh+1;
for(ia=0;ia<na;++ia){
gr=*rh*rk-*sh*sk;
gs=*rh*sk+*sh*rk;
*rh=*ri-gr;
*sh=*si-gs;
*ri=*ri+gr;
*si=*si+gs;
ri+=2;
si+=2;
rh+=2;
sh+=2;
}
}
na>>=1;
n2a>>=1;
n4a>>=1;
nb<<=1;
}
/* unscramble */
for(j=0;j<nf;++j){
k=mf[j];
if(k>j){
ri=x+(j<<1);
si=ri+1;
rh=x+(k<<1);
sh=rh+1;
gr=*ri;
gs=*si;
*ri=*rh;
*si=*sh;
*rh=gr;
*sh=gs;
}
}
/* rearrange for real input */
ri=x+2;
si=ri+1;
rh=x+2*(nf-1);
sh=rh+1;
for(k=1;k<ns;++k){
gr=*ri+*rh;
gs=*si+*sh;
hr=*ri-*rh;
hs=*si-*sh;
rk=sine[ns-k];
sk=sine[k];
fr=rk*gs-sk*hr;
*ri=gr-fr;
*rh=gr+fr;
fs=sk*gs+rk*hr;
*si=hs+fs;
*sh=fs-hs;
ri+=2;
si+=2;
rh-=2;
sh-=2;
}
*ri=2.**ri;
*si=-2.**si;
ri=x;
si=ri+1;
gr=*ri+*si;
*si=*ri-*si;
*ri=gr;
return(0);
}
/**************************************/
int play(smp,nsm,ism)
BYTE *smp; /* pointer to sound array (word aligned, chip access) */
int nsm; /* length of smp (in bytes; even) */
int ism; /* sound sample interval (clock periods of 279.365 ns) */
{
struct IOAudio *ioa0=NULL;
struct MsgPort *msg0=NULL;
int ie; /* error code */
static BYTE alr[]={1}; /* allocation mask for channel 0 */
ioa0=(struct IOAudio *)calloc(sizeof(struct IOAudio),1);
ie=1;if(ioa0==NULL) goto exitplay;
msg0=(struct MsgPort *)CreatePort("play0",0);
ie=2;if(msg0==NULL) goto exitplay;
ioa0->ioa_Data=alr;
ioa0->ioa_Length=1;
ioa0->ioa_Request.io_Message.mn_Node.ln_Pri=127; /* maximum */
ioa0->ioa_Request.io_Message.mn_ReplyPort=msg0;
ie=3;if(OpenDevice("audio.device",0,ioa0,0)!=0) goto exitplay;
ioa0->ioa_Data=smp;
ioa0->ioa_Length=nsm;
ioa0->ioa_Period=ism;
ioa0->ioa_Volume=64; /* maximum */
ioa0->ioa_Cycles=1; /* once thru */
ioa0->ioa_Request.io_Command=CMD_WRITE;
ioa0->ioa_Request.io_Flags=ADIOF_PERVOL;
BeginIO(ioa0);
WaitIO(ioa0);
ie=0;
exitplay:
if(msg0) DeletePort(msg0);
if(ioa0){
if(ioa0->ioa_Request.io_Device) CloseDevice(ioa0);
free((char *)ioa0);
}
return(ie);
}